{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# LFortran: Interactive Fortran Compiler\n",
    "\n",
    "This is a Demo notebook that was [originally used](https://nbviewer.jupyter.org/gist/certik/f1d28a486510810d824869ab0c491b1c) with the Python prototype of LFortran. The new C++ production implementation can now execute all the cells in the original notebook (and more).\n",
    "\n",
    "\n",
    "## Calculator"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "1+3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "(2+3)*3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Global Variables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "integer :: i"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "integer :: j"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "i = 5\n",
    "j = 6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "i"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "(i+j)*3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Functions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can declare a function and use it in expressions:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "integer function fn(a, b)\n",
    "integer, intent(in) :: a, b\n",
    "fn = a + b\n",
    "end function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fn(2, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fn(2, 3)*3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can redeclare a function and it will shadow the old `fn` function. Now `fn(2, 3)` returns a different value:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "integer function fn(a, b)\n",
    "integer, intent(in) :: a, b\n",
    "fn = a - b\n",
    "end function\n",
    "\n",
    "fn(2, 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Control Flow, Printing"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can use loops, if statements or the `print` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "integer :: i\n",
    "do i = 1, 4\n",
    "    if (i == 3) cycle\n",
    "    print *, \"variable i =\", i\n",
    "end do"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Plotting"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We are designing how plotting should work in [#209](https://gitlab.com/lfortran/lfortran/-/issues/209). So this prototype code is now commented out:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!integer :: i, tmp\n",
    "!do i = 1, 4\n",
    "!    tmp = plot(1, i+1, 1)\n",
    "!end do\n",
    "!show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Magic Commands"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Compiler"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "integer :: i, j, n\n",
    "n = 5\n",
    "j = 0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Show Abstract Syntax Tree (AST) after parsing (based on syntax only, no semantics):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%showast\n",
    "do i = 1, n\n",
    "    j = j + i\n",
    "end do"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Show LLVM code:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%showllvm\n",
    "do i = 1, n\n",
    "    j = j + i\n",
    "end do"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Show assembly code:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%showasm\n",
    "do i = 1, n\n",
    "    j = j + i\n",
    "end do"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Fortran",
   "language": "fortran",
   "name": "fortran"
  },
  "language_info": {
   "file_extension": ".f90",
   "mimetype": "text/x-fortran",
   "name": "fortran",
   "version": "2018"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
